#include "stdafx.h"
#include <vector>
#include <string>
#include <fstream>
#include <sstream>

#include "cObjLoader.h"
#include "imageloader.h"

cObjLoader objLoader;
cMtlLoader mtlLoader;

using std::string;
using std::istringstream;
using std::ifstream;

////////// cOBJLOADER... //////////

bool cObjLoader::loadObj(std::string file, vector<cObjMaterial> *mtl, cObjModel *model) {
	ifstream input(file.c_str());
	string buffer;

	int nV=0;
	int nT=0;
	int nN=0;
	int padV=0;
	int padT=0;
	int padN=0;

	if ( !input ) {
		return false;
	}

	cObjObject *object;

	int MtlNumber = -1;

	while ( getline(input, buffer) ) {
		std::istringstream line(buffer);
		string line_t;

		if (buffer.substr(0,1) == "o" )
		{
			string name;
			line >> line_t >> name;;

			model->object.push_back( cObjObject( name ) );

			object = &( model->object.back() );

		}
		if (buffer.substr(0,2) == "vn") {
			float f1, f2, f3;
			line >> line_t >> f1 >> f2 >> f3;
			model->normal.push_back( cObjNormal(f1, f2, f3) );
		} 
		else if (buffer.substr(0,2) == "vt") {
			float f1, f2;
			line >> line_t >> f1 >> f2;
			model->texCoord.push_back( cObjTexCoord(f1, f2) );
		} 
		else if (buffer.substr(0,1) == "v") {
			float f1, f2, f3;
			line >> line_t >> f1 >> f2 >> f3;
			model->vertex.push_back( cObjVertex(f1, f2, f3) );
		}
		else if (buffer.substr(0,2) == "us") {
			string mtlname;
			line >> line_t >> mtlname;;

			for( int i=0 ; i < mtl->size() ; i++ )
			{
				if( mtl->at(i).name == mtlname )
					MtlNumber = i;
			}
		}
		else if (buffer.substr(0,1) == "f") {
			object->face.push_back( cObjFace() );
			object->face.back().material = MtlNumber;

			string element;
			string s1, s2, s3;
			s1 = s2 = s3 = "";
			line >> line_t;

			while (line >> element) {
				string::size_type spos = 0;
				string::size_type epos;

				epos = element.find('/');
				if (epos == string::npos)
					s1 = element;
				else
				{
					s1 = element.substr(spos, epos);

					spos = epos+1;
					epos = element.find('/', spos);
					if (epos == string::npos)
					{
						s2 = element.substr(spos, element.size() -1 );
						s3 = "";
					}
					else
					{
						s2 = element.substr(spos, epos-spos);
						s3 = element.substr(epos+1);
					}
				}

				int vi, vti, vni;

				if( !s1.empty() )
				{
					istringstream vind(s1);
					vind >> vi;

					object->face.back().vertex.push_back(vi);
				}

				if( !s2.empty() )
				{
					istringstream vind(s2);
					vind >> vti;
					object->face.back().texCoord.push_back(vti);
				}

				if( !s3.empty() )
				{
					istringstream vind(s3);
					vind >> vni;
					object->face.back().normal.push_back(vni);
				}
			}
		}
	}

	input.close();

	return true;
}


bool cMtlLoader::loadMtl(std::string file, vector<cObjMaterial> *m, vector<cObjTexture> *t) {
	ifstream input(file.c_str());
	string buffer;

	if ( !input ) {
		return false;
	}


	while ( getline(input, buffer) ) {
		std::istringstream line(buffer);
		string line_t;

		if (buffer.substr(0,2) == "ne") {
			string name;
			line >> line_t >> name;
			m->push_back( cObjMaterial(name) );
		} 
		else if (buffer.substr(0,2) == "Ns") {
			float f1;
			line >> line_t >> f1;
			m->back().Ns = f1;
		} 
		else if (buffer.substr(0,2) == "Ka") {
			float f1, f2, f3;
			line >> line_t >> f1 >> f2 >> f3;
			m->back().Ka[0] = f1;
			m->back().Ka[1] = f2;
			m->back().Ka[2] = f3;
		}
		else if (buffer.substr(0,2) == "Kd") {
			float f1, f2, f3;
			line >> line_t >> f1 >> f2 >> f3;
			m->back().Kd[0] = f1;
			m->back().Kd[1] = f2;
			m->back().Kd[2] = f3;
		}
		else if (buffer.substr(0,2) == "Ks") {
			float f1, f2, f3;
			line >> line_t >> f1 >> f2 >> f3;
			m->back().Ks[0] = f1;
			m->back().Ks[1] = f2;
			m->back().Ks[2] = f3;
		}
		else if (buffer.substr(0,2) == "Ni") {
			float f1;
			line >> line_t >> f1;
			m->back().Ni = f1;
		}
		else if (buffer.substr(0,1) == "d") {
			float f1;
			line >> line_t >> f1;
			m->back().d = f1;
		}
		else if (buffer.substr(0,2) == "il") {
			int i1;
			line >> line_t >> i1;
			m->back().illum = i1;
		}
		else if(buffer.substr(0,6) == "map_Kd") {
			string name;
			line >> line_t >> name;

			m->back().bKdTexture = true;

			int k;
			for( k=0 ; k < t->size() ; k++ )
			{
				if( t->at(k).name == name )
				{
					m->back().map_Kd_texture_ID = t->at(k).id;

					break;
				}
			}

			if( k == t->size() )
			{
				Image *image = loadBMP(name.c_str());
				GLuint textureID = loadTexture(image);
				delete image;

				t->push_back( cObjTexture( name ) );
				t->back().id = textureID;
				m->back().map_Kd_texture_ID = textureID;
			}
		}
	}

	input.close();

	return true;
}
